home *** CD-ROM | disk | FTP | other *** search
Modula Implementation | 1991-06-11 | 7.6 KB | 274 lines |
- (*# call(o_a_copy => off) *)
- (*%T _fcall *)
- (*# call(seg_name => QCxm) *)
- (*%E *)
- (*%F _fcall *)
- (*# call(seg_name => null) *)
- (*%E *)
- (*# module(implementation=>on) *)
- (*# data(seg_name => null) *)
- IMPLEMENTATION MODULE QCxmzero;
-
- (* This JPI Modula-2 module is part of *)
-
- (* QC -- a communications program *)
- (* by Carl Neiburger *)
- (* 169 N. 25th St.*)
- (* San Jose, Calif. 95116 *)
-
- (* CompuServe No. 72336,2257 *)
-
- FROM Str IMPORT Append, CHARSET, Delete, Insert, Length,
- Pos, StrToCard, CardToStr, StrToCard;
- FROM FioAsm IMPORT DirEntry, TimeType, DecodeFileTime, EncodeFileTime;
- FROM Lib IMPORT Fill, Move;
- FROM QCcomm IMPORT ProgramName, soh, syn;
- IMPORT NFIO;
- FROM UTIL IMPORT str12, str80;
-
- TYPE
- BoolLongcardArray = ARRAY BOOLEAN OF LONGCARD;
- Longcard12Array = ARRAY [1..12] OF LONGCARD;
- BoolLongcard12Array = ARRAY BOOLEAN OF Longcard12Array;
-
- (* Ymodem
- FileName : ASCIIZ
- FileLength : Decimal ASCII terminated by space
- FileTime : Octal ASCII+ space, seconds since 1-1-70 GMT
-
-
- TimeType = RECORD in FioAsm
- Year, Month, Day, Hours, Mins, Secs: CARDINAL *)
-
- CONST
- SecondsPerYear = BoolLongcardArray (31536000, 31622400);
- SecondsPerDay = 86400;
- SecondsPerHour = 3600;
- SecondsPerMinute = 60;
- M31 = 31*SecondsPerDay;
- M30 = 30*SecondsPerDay;
-
- NormSecondsPerMonth = Longcard12Array
- (Longcard12Array(M31, 28*SecondsPerDay,
- M31, M30, M31, M30, M31, M31,
- M30, M31, M30, M31));
-
- SmallBlockSize = 133;
- LargeBlockSize = 1029;
-
- OKattr = NFIO.FileAttr{NFIO.readonly,NFIO.archive};
-
- VAR
- SecondsPerMonth : Longcard12Array;
-
- PROCEDURE BasicBlock(VAR b: BPtr);
- BEGIN
- Fill( b, SmallBlockSize, 0);
- b^[1] := soh;
- b^[3] := 255; (* [2] set to zero by Fill *)
- END BasicBlock;
-
- PROCEDURE LeapYear(y: CARDINAL): BOOLEAN;
- BEGIN
- RETURN y MOD 4 = 0
- END LeapYear;
-
- PROCEDURE February(y : CARDINAL);
- BEGIN
- IF LeapYear(y) THEN
- SecondsPerMonth[2] := 29*SecondsPerDay
- ELSE
- SecondsPerMonth[2] := 28*SecondsPerDay
- END
- END February;
-
- PROCEDURE SecondsToDate(s: LONGCARD; base: CARDINAL): LONGCARD;
- VAR d: TimeType;
- BEGIN
- Fill( ADR(d), SIZE(d), 0);
- d.Year := base;
- WHILE s > SecondsPerYear[LeapYear(d.Year)] DO
- DEC(s, SecondsPerYear[LeapYear(d.Year)]);
- INC(d.Year);
- END;
- d.Month := 1;
- February(d.Year);
- WHILE (s>SecondsPerMonth[d.Month]) DO
- DEC(s, SecondsPerMonth[d.Month]);
- INC(d.Month)
- END;
- d.Day := VAL(CARDINAL, s DIV SecondsPerDay) + 1;
- s := s MOD SecondsPerDay;
- d.Hours := VAL(CARDINAL, s DIV SecondsPerHour);
- s := s MOD SecondsPerHour;
- d.Mins := VAL(CARDINAL, s DIV SecondsPerMinute);
- d.Secs := VAL(CARDINAL, s MOD SecondsPerMinute);
- RETURN EncodeFileTime(d)
- END SecondsToDate;
-
- PROCEDURE DateToSeconds(s: LONGCARD; base: CARDINAL): LONGCARD;
- VAR n: CARDINAL; d: TimeType;
- BEGIN
- DecodeFileTime(s, d);
- s := 0;
- FOR n := base TO d.Year - 1 DO
- INC(s, SecondsPerYear[LeapYear(n)])
- END;
- February(d.Year);
- FOR n := 1 TO d.Month - 1 DO
- INC(s, SecondsPerMonth[n])
- END;
- INC(s, VAL(LONGCARD, d.Day - 1) * SecondsPerDay);
- INC(s, VAL(LONGCARD, d.Hours) * SecondsPerHour);
- INC(s, VAL(LONGCARD, d.Mins) * SecondsPerMinute);
- INC(s, VAL(LONGCARD, d.Secs) );
- RETURN s
- END DateToSeconds;
-
- PROCEDURE CreateYZModemBlock(fname: ARRAY OF CHAR;
- VAR tname: PathTail; VAR b: BPtr; Z: CARDINAL): CARDINAL;
- VAR DE : DirEntry; i, len: CARDINAL; s: str12; l : LONGCARD; valid : BOOLEAN;
- BEGIN
- tname[0] := 0C;
- BasicBlock(b);
- IF NOT NFIO.ReadFirstEntry(fname, OKattr, DE) THEN
- RETURN 0
- END;
- FOR i := 0 TO Length(DE.Name)-1 DO
- IF DE.Name[i] IN CHARSET {'A'..'Z'} THEN
- INC(DE.Name[i],32); (* change to lower case *)
- END
- END;
- Move( ADR(DE.Name), ADR(b^[Z]), i+1);
- INC(i,Z+2); (* start of block, and leave a nul *);
- CardToStr( VAL(LONGCARD, DE.size), s, 10, valid);
- Append(s, ' ');
- len := Length(s);
- Move( ADR(s), ADR(b^[i]), len);
- INC(i, len);
- l := DateToSeconds( VAL(LONGCARD, DE.date)<<16
- + VAL(LONGCARD, DE.time), 1970);
- CardToStr( l, s, 8, valid );
- Append(s, ' ');
- len := Length(s);
- Move( ADR(s), ADR(b^[i]), len);
- RETURN i + len + 1
- END CreateYZModemBlock;
-
- PROCEDURE CreateYModemBlock(fname: ARRAY OF CHAR;
- VAR tname: PathTail; VAR b: BPtr): CARDINAL;
- BEGIN
- RETURN CreateYZModemBlock(fname, tname, b, 4 )
- END CreateYModemBlock;
-
- PROCEDURE CreateZModemBlock(fname: ARRAY OF CHAR;
- VAR tname: PathTail; VAR b: BPtr ): CARDINAL;
- BEGIN
- RETURN CreateYZModemBlock(fname, tname, b, 1)
- END CreateZModemBlock;
-
-
- PROCEDURE CreateTelinkBlock(fname: ARRAY OF CHAR;
- VAR tname: PathTail; VAR b: BPtr): CARDINAL;
- VAR DE : DirEntry; i: CARDINAL;
- BEGIN
- BasicBlock(b);
- b^[1] := syn;
- IF NOT NFIO.ReadFirstEntry(fname, OKattr, DE) THEN
- tname := ' ';
- RETURN 0
- END;
- Move( ADR(DE.size), ADR(b^[4]), 4 );
- Move( ADR(DE.time), ADR(b^[8]), 4 );
- Move( ADR(DE.Name), ADR(b^[12]), Length(DE.Name));
- Move( ADR(ProgramName), ADR(b^[29]), 2);
- tname := DE.Name;
- i := Pos(tname, '.');
- IF i < MAX(CARDINAL) THEN
- Delete(tname, i, 1);
- ELSE
- i := Length(tname);
- END;
- WHILE Length(tname) < 11 DO
- Insert(tname, ' ', i)
- END;
- RETURN 128
- END CreateTelinkBlock;
-
- PROCEDURE InterpretYModemBlock(b: BPtr; VAR t: TelinkBlockType);
- VAR i, p: CARDINAL; s: str80; OK: BOOLEAN;
-
- PROCEDURE ReturnString(): str80;
- TYPE SPtr = POINTER TO str80;
- VAR sp : SPtr;
- BEGIN
- sp := ADR(b^[i]);
- INC(i, Length(sp^) + 1);
- RETURN sp^
- END ReturnString;
-
- PROCEDURE DefineNumStr(CS: CHARSET);
- (*
- PROCEDURE DefineNumStr(Hi: CHAR);
- *)
- BEGIN
- p := i;
- (*
- WHILE CHR(b^[p]) IN CHARSET{'0'..Hi} DO
- *)
- WHILE CHR(b^[p]) IN CS DO
- INC(p)
- END;
- b^[p] := 0
- END DefineNumStr;
-
- BEGIN
- i := 1;
- Fill( ADR(t), SIZE(t), 0);
- s := ReturnString();
- REPEAT
- p := Pos(s, '/');
- IF p < MAX( CARDINAL) THEN
- Delete(s, 0, p+1)
- END
- UNTIL p = MAX( CARDINAL);
- REPEAT
- p := Pos(s, '\');
- IF p < MAX( CARDINAL) THEN
- Delete(s, 0, p+1)
- END
- UNTIL p = MAX( CARDINAL);
- Move( ADR(s), ADR(t.FileName), Length(s));
- (*
- DefineNumStr('9');
- *)
- DefineNumStr(CHARSET{'0'..'9'});
- t.FileLength := StrToCard( ReturnString(), 10, OK );
- IF NOT OK THEN
- t.FileLength := 0
- END;
- (*
- DefineNumStr('7');
- *)
- DefineNumStr(CHARSET{'0'..'7'});
- t.FileTime := SecondsToDate(StrToCard(ReturnString(), 8, OK), 1970);
- IF NOT OK THEN
- t.FileTime := 0
- END;
- END InterpretYModemBlock;
-
- PROCEDURE InterpretTelinkBlock (b: BPtr; VAR t: TelinkBlockType);
- BEGIN
- Move( b, ADR(t), SIZE(t))
- END InterpretTelinkBlock;
-
- BEGIN
- SecondsPerMonth := NormSecondsPerMonth;
- CreateBlock[YModem] := CreateYModemBlock;
- CreateBlock[ZModem] := CreateZModemBlock;
- CreateBlock[Telink] := CreateTelinkBlock;
- InterpretBlock[YModem] := InterpretYModemBlock;
- InterpretBlock[ZModem] := InterpretYModemBlock;
- InterpretBlock[Telink] := InterpretTelinkBlock;
- END QCxmzero.
-